package threading.tests;

import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;

import jccr.Coordinate;
import jccr.Port;
import jccr.TaskQueue;
import jccr.ThreadPool;

import org.junit.After;
import org.junit.Assert;
import org.junit.Before;

public class TestUnitBase extends Assert {

	@Before
	public void setup() {
		_pool = new ThreadPool("T", 3);
		_queue = new TaskQueue(_pool);
		_trace = new TracePort();
		_coord = new Coordinate( _queue );
	}
	
	@After
	public void teardown() throws Exception {	
		_pool.dispose();
	}
		
	void newLatch() {
		newLatch(1);
	}
	
	void newLatch( int count ) {
		assert( _latch == null );
		_latch = new CountDownLatch(count);
	}
	
	void awaitLatch() throws Exception {
		awaitLatch( DEFAULT_LATCH_WAIT );
	}
	
	void awaitLatch(long wait) throws Exception {
		
		assertTrue( "latch await() failed due to timeout", 
				_latch.await(wait, TimeUnit.MILLISECONDS) );
	}

	
	public class TracePort extends Port<String> {
		
		public TracePort() {		
		}
		
		@Override
		public void execute( String arg ) {
	
			int count = _count.incrementAndGet();
			
			String text = Thread.currentThread().getName() + " " + arg + "count: " + count;			
			System.out.println(text);
			
			if ( _latch != null )
				_latch.countDown();
		}
		
		public int callCount() { return _count.get(); }
		
		AtomicInteger _count = new AtomicInteger();
	}	
		
	protected CountDownLatch _latch;
	protected Coordinate _coord;
	protected TracePort _trace;
	protected ThreadPool _pool;	
	protected TaskQueue _queue;
		
	public static final int DEFAULT_LATCH_WAIT = 1500; 
}
